#include "Book_t.h"
#include "Borrower_t.h"
#include "LibraryException.h"

bool Book_t::borrow(const Borrower_t * borrower) {
	if (!isAvailable()) { //no available copies
		waiting_borrowers_.push_back(borrower);
		return false;
	}

	borrowers_.push_back(borrower);
	num_of_borrowed_copies_++;

	return true;
}

const Borrower_t * Book_t::returnCopy(const Borrower_t * borrower) {
	list<const Borrower_t *>::iterator it = borrowers_.begin();
	while (it!=borrowers_.end()) {
		if (*it == borrower)
			break;
		it++;
	}
	if (it == borrowers_.end()) //Not lended to this borrower
		throw CantReturnBookExeption();

	borrowers_.erase(it);
	num_of_borrowed_copies_--;
	const Borrower_t * pBorrower = NULL;
	if (waiting_borrowers_.size() > 0) { //get the first waiting borrower
		pBorrower = waiting_borrowers_.front();
		waiting_borrowers_.pop_front();
	}
	return pBorrower;
}

ostream &operator<< (ostream& os, const Book_t & book) {
	os << "ISBN: " << book.isbn_ << endl \
		<< "Name: " << book.name_ << endl \
		<< "Author: " << book.author_ << endl \
		<< "Total copies: " << book.num_of_copies_ << endl \
		<< "Available copies: " << (book.num_of_copies_ - book.num_of_borrowed_copies_) << endl;

	os << endl << "Lended to: " << endl;
	int i = 1;
	list<const Borrower_t *>::const_iterator it = book.borrowers_.begin();
	while (it!=book.borrowers_.end()) {
		os << i++ << ": " << (*it)->getName() << ", " << (*it)->getId() << endl;
		it++;
	}
	if (i == 1) os << "(none)" << endl;

	os << endl << "Waiting for this book: " << endl;
	i = 1;
	it = book.waiting_borrowers_.begin();
	while (it!=book.waiting_borrowers_.end()) {
		os << i++ << ": " << (*it)->getName() << ", " << (*it)->getId() << endl;
		it++;
	}
	if (i == 1) os << "(none)" << endl;

	return os;

}